require 'permission_request'

# use AR namespace to reduce clashes
#
module ActiveRecord
  module Permissions
    
    # extend ActiveRecord::Base to add check user permission
    # before CRUD-type method calls
    #
    # NOTE: it would have been nice to use the ActiveRecord filters
    # system here, but there were Thread issues with SQLite... so
    # that was abandoned :(
    #
    def self.included(base)
      base.extend(ClassMethods)
      base.class_eval do
        alias_method_chain :save, :permission        
        alias_method_chain :destroy, :permission
        class <<self
          alias_method_chain :find, :permission
        end
      end
    end
    
    module ClassMethods
      
      # request an authorization from somewhere
      # further up the call stack
      #
      def permission_to?(action, target=self)
        PermissionRequest.throw!(action, target)
        return true    
      end
      
      # check permissions on read
      #
      def find_with_permission(*args)
        permission_to? :read
        find_without_permission(*args)
      end   
      
    end
        
    # shortcut to the class-method .permission_to?
    #
    def permission_to?(action)
      self.class.permission_to?(action, self)
    end  

    # check permissions on creation or update
    #
    def save_with_permission
      action = new_record? ? :create : :update
      permission_to? action
      save_without_permission
    end

    # check permission on destroy
    #
    def destroy_with_permission
      permission_to? :destroy
      destroy_without_permission
    end

  end
end

# include on Base
ActiveRecord::Base.send :include, ActiveRecord::Permissions
